package database

import (
	"JoRedis/aof"
	"JoRedis/config"
	redis2 "JoRedis/interface/redis"
	"JoRedis/interface/reply"
	"JoRedis/lib/logger"
)

type DataBase struct {
	dbPtrSlc []*DB
	aofPtr   *aof.AofHandler
}

func MakeDataBase() *DataBase {
	// 默认16个DB
	if config.PropPtr.Databases == 0 {
		config.PropPtr.Databases = 16
	}
	dbLen := config.PropPtr.Databases
	dbPtrSlc := make([]*DB, dbLen)
	for i := 0; i < dbLen; i++ {
		dbPtrSlc[i] = MakeDB(i)
	}
	databasePtr := &DataBase{dbPtrSlc: dbPtrSlc}
	if config.PropPtr.AppendOnly {
		databasePtr.aofPtr, _ = aof.MakeAofHandler(databasePtr)
		logger.Info("开启AOF")
	}
	return databasePtr
}

// Exec 执行指令(在客户端连接的DB上执行)
func (this *DataBase) Exec(redisConn redis2.RedisConnItf, cmdBytesSlc [][]byte) reply.ReplyItf {
	dbIndex := redisConn.GetDBIdx()
	dbPtr := this.dbPtrSlc[dbIndex]
	execReply := dbPtr.ExecCmd(redisConn, cmdBytesSlc)
	this.writeAof(redisConn, cmdBytesSlc)
	return execReply
}

// 写入AOF文件
func (this *DataBase) writeAof(redisConn redis2.RedisConnItf, cmdBytesSlc [][]byte) {
	cmdName := string(cmdBytesSlc[0])
	cmdExecutor := cmdKeyExecutorMap[cmdName]
	if cmdExecutor.aofWrite && config.PropPtr.AppendOnly {
		this.aofPtr.AddAof(redisConn.GetDBIdx(), cmdBytesSlc)
	}
}

// Close 关闭整个Redis数据库
func (this *DataBase) Close() {
	// 关闭AOF文件
	this.aofPtr.Close()
}
